package main

import (
	"fmt"
	"io"
	"net"
	"time"
	"zinx/znet"
)

// 模拟客户端
func main() {
	// 直连远程服务器，得到一个conn链接
	fmt.Println("client start.......")
	time.Sleep(1 * time.Second) //挂起1s
	conn, err := net.Dial("tcp", "127.0.0.1:8999")
	if err != nil {
		fmt.Println("client start err,exit")
		return
	}

	for {
		/*
				//链接调用Write 写数据
				_, err := conn.Write([]byte("hello zinx V0.1..")) //返回的字节数暂时不关心
				if err != nil {
					fmt.Println("write conn err", err)
					return
				}
				buf := make([]byte, 512)
				cnt, err := conn.Read(buf)
				if err != nil {
					fmt.Println("read buf error")
					return
				}
				fmt.Printf("severr call back:%s,cnt=%d\n", buf, cnt)
				//CPU阻塞，否则会无限循环

				time.Sleep(1 * time.Second) //每隔一秒发一次 hello zinx V0.1..
			}
		*/
		//发送封包的message消息，MsgId：0
		dp := znet.NewDataPack()
		binaryMsg, err := dp.Pack(znet.NewMsgPackage(0, []byte("zinxv0.5 client test message")))
		if err != nil {
			fmt.Println("pack error", err)

		}
		if _, err := conn.Write(binaryMsg); err != nil {
			fmt.Println("write error", err)
			return
		}
		//服务器应该返回一个message数据，MsgId：1,ping...ping...ping
		// 依然是两次读取
		//先读head部分
		binaryHead := make([]byte, int(dp.GetHeadLen()))
		if _, err := io.ReadFull(conn, binaryHead); err != nil {
			fmt.Println("read head error", err)
			break

			// 	_, err := io.ReadFull(conn, binaryHead); 这样写会报错，因为err变量用过了，所以可以放在if语句中，这是一个新的定义域
			// if err != nil {
			// 	fmt.Println("read head error", err)
			// 	break
		}
		//将headData字节流 拆包到msg中
		msgHead, err := dp.Unpack(binaryHead)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if msgHead.GetDataLen() > 0 {
			//msg 是有data数据的，需要再次读取data数据
			msg := msgHead.(*znet.Message)
			msg.Data = make([]byte, msg.GetDataLen())

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, msg.Data)
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}
			fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
		}
		time.Sleep(1 * time.Second)
	}

}
